<?php
/**
 * Created by PhpStorm.
 * User: cc
 * Date: 2024/8/26
 * Time: 14:55
 */

namespace app\common\lib\sfkd;

use app\common\lib\Util;
use think\Env;
use think\Log;

class SfKd
{
    /**
     * 顺丰测试环境配置
     * @var string[]
     */
    protected $betaConfig = [
        'cust_id' => '9999999999',
        'app_id' => '987922013266944000',
        'sk' => 'b1cfd03d49f653d6fce903e22711744c',
        'host' => 'https://butler-dev.sit.sf-express.com'
    ];

    /**
     * 顺丰配置
     * @var string[]
     */
    protected $config = [
        'cust_id' => '0101909244',
        'app_id' => '986876773826363392',
        'sk' => 'a06163335a017362f4e26d992a6bf561',
        'host' => 'https://butler-ms.sf-express.com'
    ];

    public $kdType = [
        1 => '顺丰特快',
        2 => '顺丰标快',
        6 => '顺丰即日',
        263 => '同城半日达',
    ];

    /**
     * 寄件信息
     * @var string[]
     */
    public $sendInfo = [
        'company' => '北京星座女神文化传媒有限公司',
        'name' => '黑博士疗愈水晶',
        'phone' => '18310273851',
        'address' => '北京市朝阳区高碑店花园里文创园c3009'
    ];

    public function __construct()
    {
        if (Env::get('hosts.name') === 'online')
        {
            $this->config = $this->betaConfig;
        }
    }

    /**
     * 查看物流信息(3个月内的订单)
     * @param $waybillNo
     * @param $tel
     * @return array
     */
    public function getRouteInfo($waybillNo, $tel)
    {
        $data = [
            'companyId' => $this->config['app_id'],
            'trackingType' => 1,
            'trackingNumber' => $waybillNo,//1-如果trackingType=1，则此值为顺丰运单号；2-如果trackingType=2，则此值为客户订单号
            'checkPhoneNo' => substr($tel, -4),//收寄人任一方电话号码后4位，
        ];
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $url = $this->config['host'] . '/public/order/v2/listOrderRoute';
        $res = $this->sendUrl($data, $url);
        if ($res['succ'] === 'fail')
        {
            Log::write('获取顺丰快递路由异常：' . json_encode($res, JSON_UNESCAPED_UNICODE), 'sf_kd_err', true);
            return [
                'status' => false,
                'msg' => $res['msg'],
                'data' => []
            ];
        }
        return [
            'status' => true,
            'msg' => $res['msg'],
            'data' => $res['result']
        ];
    }

    /**
     * 下单
     * @param string $orderId 订单编号
     * @param array $userInfo 收货信息
     * @param array $goodsInfo 商品信息
     * @param array $shipmentsInfo 发货信息
     * @return array|void
     */
    public function payOrder($orderId, $userInfo, $goodsInfo, $shipmentsInfo)
    {
        try
        {
            [$province, $city, $area, $detail] = explode(' ', $userInfo['address']);
            // 接口参数
            $data = [
                'companyId' => $this->config['app_id'],
                'orderId' => $orderId,
                'sendstarttime' => '',
                'jCompany' => $shipmentsInfo['company'],
                'jContact' => $shipmentsInfo['name'],
                'jMobile' => $shipmentsInfo['phone'],
                'jAddress' => $shipmentsInfo['address'],
                'dContact' => $userInfo['name'],
                'dMobile' => $userInfo['phone'],
                'dProvince' => $province,
                'dCity' => $city,
                'dAddress' => $area . $detail,
                'custid' => $this->config['cust_id'],//月结卡号 测试环境
                'payMethod' => '0',//0-寄付月结；1-寄付现结；2-收方付；3-第三方付；
                'expressType' => $shipmentsInfo['kd_type'],///快件产品类别
                'packagesNo' => '1',//包裹件数
                'depositumInfo' => $goodsInfo['name'],
                'depositumNo' => $shipmentsInfo['num'],//托寄物数量
                'remark' => $shipmentsInfo['remark'],
                'isDoCall' => '0',//是否通过手持终端通知顺丰收派员上门收件
                'isReceipt' => '0',//是否纸质签回单
                'isSelfGet' => '1',//是否自取
                'supportValue' => '0',//保价金额
                'isCollection' => '0',//是否代收
                'collectionMoney' => '0',//代收金额
                'expressBillType' => '1',//1-内地互寄；0-港澳台+国际
                'personalExpress' => '1',//0-个人件；1-企业件
                'creatorUser' => '17333657763',//填顺丰快递管家中真实账号
                'volume' => '0',//订单货物总体积，
            ];
            $data = json_encode($data, JSON_UNESCAPED_UNICODE);
            $url = $this->config['host'] . '/public/order/v2/placeOrder';
            $res = $this->sendUrl($data, $url);
            Log::write('顺丰下单：' . json_encode($res, JSON_UNESCAPED_UNICODE), 'sf_kd', true);
            if ($res['succ'] === 'fail')
            {
                Log::write('顺丰下单异常：' . json_encode($res, JSON_UNESCAPED_UNICODE), 'sf_kd_err', true);
                return [
                    'status' => false,
                    'msg' => $res['msg'],
                    'data' => []
                ];
            }
            return [
                'status' => true,
                'msg' => $res['msg'],
                'data' => $res['result']
            ];
        }
        catch (\Exception $e)
        {
            Log::write('顺丰下单异常：' . $e->getMessage() . ',订单:' . $orderId . ',用户信息:' . json_encode($userInfo, JSON_UNESCAPED_UNICODE), 'sf_kd_err', true);
            return [
                'status' => false,
                'msg' => $e->getMessage(),
                'data' => []
            ];
        }
    }

    /**
     * 修改下单内容
     * @return array
     */
    public function alterOrder($orderId, $userInfo, $waybillNoInfoList, $expressType)
    {
        [$province, $city, $area, $detail] = explode(' ', $userInfo['address']);
        $data = [
            'companyId' => $this->config['app_id'],
            'orderId' => $orderId,
            'dealType' => 1,
            'mailNo' => current($waybillNoInfoList)['waybillNo'],
            'isConfirmNew' => 1,
            'contact' => $userInfo['name'],
            'mobile' => $userInfo['phone'],
            'province' => $province,
            'city' => $city,
            'county' => $area,
            'address' => $detail,
            'expressType' => $expressType,//快件产品类别
            'waybillNoInfoList' => $waybillNoInfoList,
        ];
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $url = $this->config['host'] . '/public/order/v2/cancelOrder';
        $res = $this->sendUrl($data, $url);
        if ($res['succ'] === 'fail')
        {
            Log::write('顺丰修改用户信息异常：' . json_encode($res, JSON_UNESCAPED_UNICODE), 'sf_kd_err', true);
            return [
                'status' => false,
                'msg' => $res['msg'],
                'data' => []
            ];
        }
        return [
            'status' => true,
            'msg' => $res['msg'],
            'data' => $res['result']
        ];
    }

    /**
     * 取消订单
     * @param $orderId
     * @return array
     */
    public function cancelOrder($orderId)
    {
        $data = [
            'companyId' => $this->config['app_id'],
            'orderId' => $orderId
        ];
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        $url = $this->config['host'] . '/public/order/v2/cancelOrder';
        $res = $this->sendUrl($data, $url);
        if ($res['succ'] === 'fail')
        {
            Log::write('顺丰取消发货异常：' . json_encode($res, JSON_UNESCAPED_UNICODE), 'sf_kd_err', true);
            return [
                'status' => false,
                'msg' => $res['msg'],
                'data' => []
            ];
        }
        return [
            'status' => true,
            'msg' => $res['msg'],
            'data' => $res['result']
        ];
    }


    /**
     * 发送请求
     * @param $data
     * @param $url
     * @return mixed
     */
    private function sendUrl($data, $url)
    {
        // 签名
        $timestamp = time() . '000';
        $signData = $data . '&sk=' . $this->config['sk'] . '&timestamp=' . $timestamp;
        $sha512 = hash('sha512', $signData, true);
        $base64 = base64_encode($sha512);
        $sign = str_replace(['+', '/', '='], ['-', '_'], $base64);

        // 发送请求
        $headers = [
            "Content-type:application/json;charset='utf-8'",
            "Accept:application/json",
            "sendAppId:" . $this->config['app_id'],
            "timestamp:" . $timestamp,
            "sign:" . $sign
        ];
        $res = Util::curlRequest('POST', $url, $data, $headers);
        return json_decode($res, true);
    }

    /**
     * Des加解密工具类
     * @param $hex
     * @return string
     */
    public function hexToStr($hex)
    {
        $str = "";
        for ($i = 0; $i < strlen($hex) - 1; $i += 2)
            $str .= chr(hexdec($hex[$i] . $hex[$i + 1]));
        return $str;
    }

    /**
     * 加解密demo
     * @return void
     */
    protected function esAndDes()
    {
        // SK,顺丰快递管家分配的SK
        $KEY = $this->config['sk'];
        $hex = '0102030405060708';
        $IV = $this->hexToStr($hex);

        // 要加解密的文本
        $data = 'test';
        $en = base64_encode(openssl_encrypt($data, 'des-ede3-cbc', base64_decode($KEY), OPENSSL_RAW_DATA, $IV));
        echo "加密后：" . $en . "\r\n";
        $de = openssl_decrypt(base64_decode($en), 'des-ede3-cbc', base64_decode($KEY), OPENSSL_RAW_DATA, $IV);
        echo "解密后：" . $de . "\r\n";
    }
}
